package com.mayflygeek.mayflyask.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mayflygeek.mayflyask.dao.UserDao;
import com.mayflygeek.mayflyask.entity.User;
import com.mayflygeek.mayflyask.service.UserService;
import com.mayflygeek.mayflyask.util.MD5Utils;
/**
 * @author 蝈蝈 
 * @email guodefu909@126.com
 * @team 蜉蝣极客
 * @link www.mayflygeek.com
 * 通过 User 做的增删改查示例，包括分页示例
 */
@Service
@Transactional
public class UserServiceImpl implements UserService{
	
	private Logger log = LoggerFactory.getLogger(getClass());
	/* @Resource的作用相当于@Autowired
	 * @Autowired是spring自己定义的，@Resource是JSR-250规范定义的
	 * 推荐使用：@Resource，减少了与spring的耦合。
	 * 两者的更多区别参考：http://blog.csdn.net/gst6062825/article/details/8765157*/
	@Resource
	private UserDao userDao;

	@Override
	public User saveUser(User user) {
		log.info("UserService.saveUser:"+user.toString());
		user.setPassword(MD5Utils.encode(user.getPassword() + user.getSalt()));
		return userDao.save(user);
	}

	@Override
	public void deleteUser(Long id) {
		if(userDao.exists(id)){
			userDao.delete(id);
		}
	}
	@Override
	public int deleteUserByIds(List<Long> ids) {
		return userDao.deleteUserByIds(ids);
	}
	
	@Override
	public int deleteUserByIds(String ids) {
		if (ids==null || "".equals(ids)) {
			return 0;
		}
		String[] idsArr = ids.split(",");
		List<Long> list = new ArrayList<>();
		for (String idStr : idsArr) {
			list.add(Long.parseLong(idStr));
		}
		return userDao.deleteUserByIds(list);
	}

	@Override
	public void deleteUser(User user) {
		userDao.delete(user);
	}

	@Override
	public void deleteUsers(List<User> users) {
		userDao.deleteInBatch(users);
	}
	
	@Override
	public User updateUser(User user) {
		user.setPassword(MD5Utils.encode(user.getPassword() + user.getSalt()));
		return userDao.saveAndFlush(user);
	}

	@Override
	public int updateUserStatus(Long id, Integer status) {
		return userDao.updateUserStatus(status, id);
	}
	
	@Override
	public int updateUserPassword(Long id,String password) {
		return userDao.updateUserPassword(id, password);
	}

	@Override
	@Transactional(readOnly=true)
	public User getUser(Long id) {
		return userDao.findOne(id);//一般不用getOne
	}
	
	@Override
	@Transactional(readOnly=true)
	public User getByUserName(String userName) {
		return userDao.getByUserName(userName);
	}
	
	@Override
	@Transactional(readOnly=true)
	public List<User> getAllUser() {
		return userDao.findAll();
	}
	
	@Override
	@Transactional(readOnly=true)
	public Page<User> getPage(int pageNumber, int pageSize){
		PageRequest pageable = new PageRequest(pageNumber - 1, pageSize);
		return userDao.findAll(pageable);
	}
	
	@Override
	@Transactional(readOnly=true)
	public Page<User> getPageByUserNameNickName(int pageNumberParam,int pageSizeParam,String userNameParam,String nickNameParam) {
		String userName = userNameParam == null ? "" : userNameParam;
		String nickName = nickNameParam == null ? "" : nickNameParam;
		int pageNumber = pageNumberParam < 1 ? 1 : pageNumberParam;
		int pageSize = pageSizeParam < 1 ? 10 : pageSizeParam;
		PageRequest pageable = new PageRequest(pageNumber - 1, pageSize);
		return userDao.findByUserNameLikeAndNickNameLike("%"+userName+"%", "%"+nickName+"%", pageable);
	}
	
	@Override
	@Transactional(readOnly=true)
	public Page<User> getPageByUserNameNickName1(int pageNumber,int pageSize,String userNameParam,String nickNameParam) {
		String userName = userNameParam == null ? "" : userNameParam;
		String nickName = nickNameParam == null ? "" : nickNameParam;
		
		PageRequest pageable = new PageRequest(pageNumber - 1, pageSize);
		
		//通常使用 Specification 的匿名内部类
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate nickNamePredicate = !"".equals(nickName) ? cb.like(root.get("nickName"), "%" + nickName + "%") : null;
				Predicate userNamePredicate = !"".equals(userName) ? cb.like(root.get("userName"), "%" + userName + "%") : null;
				Predicate predicate = null;
				if (!"".equals(userName) && !"".equals(nickName)) {
					predicate = cb.and(userNamePredicate, nickNamePredicate);
				} else if (!"".equals(userName)) {
					predicate = userNamePredicate;
				} else if (!"".equals(nickName)) {
					predicate = nickNamePredicate;
				}
				return predicate;
			}
		};
		
		return userDao.findAll(specification, pageable);
	}
	

}
